package cn.zxcoder.controller.SystemManage.right;

import cn.zxcoder.Tools.ToolUtil;
import cn.zxcoder.entity.Res;
import cn.zxcoder.entity.RoleRight;
import cn.zxcoder.entity.SystemManage.Menu;
import cn.zxcoder.entity.SystemManage.Right;
import cn.zxcoder.entity.SystemManage.Role;
import cn.zxcoder.service.IMenuService;
import cn.zxcoder.service.IRightService;
import cn.zxcoder.service.IRoleRightService;
import cn.zxcoder.service.IRoleService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;

import java.util.*;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author zx
 * @since 2023-05-12
 */
@RestController
@Api(tags = "用于做权限管理的前端控制器")
@RequestMapping("/api/Permission")
public class RightController {


    @Autowired
    IRightService iRightServiceIml;

    @Autowired
    IRoleService iRoleServiceIml;

    @Autowired
    IMenuService iMenuServiceIml;

    @Autowired
    IRoleRightService iRoleRightServiceIml;


    @ApiOperation(value = "获取所有权限列表")
    @PostMapping("/list")
    @Transactional(readOnly = true)
    public Res getRight(@RequestParam String page, @RequestParam String limit, @RequestParam String rightName,
                        @RequestParam String rightCode) {

        Page<Right> rightPage = new Page<>(Integer.parseInt(page), Integer.parseInt(limit));
        QueryWrapper<Right> rightQueryWrapper = new QueryWrapper<>();
        if (!rightName.equals("")) {
            rightQueryWrapper.like("right_name", rightName);
        }
        if (!rightCode.equals("")) {
            rightQueryWrapper.like("right_code", rightCode);
        }
        Page<Right> page1 = iRightServiceIml.page(rightPage, rightQueryWrapper);
        return new Res(true, JSON.toJSONString(page1), "获取权限列表成功");
    }


    @ApiOperation(value = "保存权限")
    @PostMapping("/save")
    @Transactional
    public Res saveRight(@RequestParam String rightId, @RequestParam String rightName, @RequestParam String rightCode,
                         @RequestParam String token,@RequestParam boolean issave,@RequestParam boolean isOp) {

        Right right = new Right();
        right.setRightName(rightName);
        right.setRightCode(rightCode);
        right.setEditTime(new Date());
        right.setEditUser(token);
        right.setOp(isOp);

        //这里做父级节点schildren属性的设定  （我们的菜单权限分为3级别）
        String[] rank = rightCode.split(":");
        if (rank.length > 3) {
            return new Res(false, null, "设置的权限CODE不符合规则(最长为3个层级)");

        }

        /**
         * 首先如果此权限是菜单权限，那么直接在此权限中设置menu_id(对应的菜单id)
         */
        if (!isOp) {//是菜单权限
            //先找到对应的菜单名
            String[] split = rightName.split(":");
            String menuName = split[split.length - 1];
            //获取对应的菜单信息
            QueryWrapper<Menu> wrapper = new QueryWrapper<>();
            wrapper.eq("name", menuName);
            Menu menu = iMenuServiceIml.getOne(wrapper);
            //设置对应的菜单id
            right.setMenuId(menu.getId());
        }




        //保存
        if (issave) {

            /**
             * 先保存此权限
             */
            boolean save = iRightServiceIml.save(right);
            if (!save) {
                return new Res(false, null, "#保存权限失败");
            }


            /**
             * 下面再设置父级权限的schildren字符串
             */

            //查询此权限对象保存后得到的id值
            QueryWrapper<Right> rightQueryWrapper1 = new QueryWrapper<>();
            rightQueryWrapper1.eq("right_code", rightCode);
            Integer id = iRightServiceIml.getOne(rightQueryWrapper1).getId();

            if (rank.length == 2) {//当数组长度为2，代表父级节点是顶级节点 eg:system:role
                String parentCode = rank[0];

                //获取父级权限的条件构造器
                QueryWrapper<Right> rightQueryWrapper = new QueryWrapper<>();
                rightQueryWrapper.eq("right_code", parentCode);

                //返回最终的schildren
                String schildren = ToolUtil.setSchildren(iRightServiceIml, id, rightQueryWrapper);
                if (schildren == null) {//说明父级的代码都写错了，没有这样的代码
                    return new Res(false, null, "#没有这样的权限CODE");
                }

                //设置父级权限的条件构造器
                UpdateWrapper<Right> rightUpdateWrapper = new UpdateWrapper<>();
                rightUpdateWrapper.eq("right_code", parentCode);
                rightUpdateWrapper.set("schildren", schildren);

                boolean update = iRightServiceIml.update(rightUpdateWrapper);

                return new Res(update, null, update ? "保存权限成功" : "保存权限失败");

            } else if (rank.length == 3) {//当数组长度为3，代表父级节点是二级节点 eg:system:role:save
                String parentCode = rank[0]+":"+rank[1];

                //获取父级权限的条件构造器
                QueryWrapper<Right> rightQueryWrapper = new QueryWrapper<>();
                rightQueryWrapper.eq("right_code", parentCode);

                //返回最终的schildren
                String schildren = ToolUtil.setSchildren(iRightServiceIml, id, rightQueryWrapper);
                if (schildren == null) {//说明父级的代码都写错了，没有这样的代码
                    return new Res(false, null, "#没有这样的权限CODE");
                }
                //设置父级权限的条件构造器
                UpdateWrapper<Right> rightUpdateWrapper = new UpdateWrapper<>();
                rightUpdateWrapper.eq("right_code", parentCode);
                rightUpdateWrapper.set("schildren", schildren);

                boolean update = iRightServiceIml.update(rightUpdateWrapper);

                return new Res(update, null, update ? "保存权限成功" : "保存权限失败");

            }//注意：顶级节点是没有父级节点的，所以不需要设置children

        }

        //编辑
        else {
            /**
             * 先更新此权限
             */
            right.setId(Integer.parseInt(rightId));
            boolean b = iRightServiceIml.updateById(right);
            if (!b) {
                return new Res(false, null, "#编辑权限失败");
            }

            /**
             * 再设置父级权限的schildren字符串
             */

            if (rank.length == 2) {//当数组长度为2，代表父级节点是顶级节点 eg:system:role
                String parentCode = rank[0];

                //获取父级权限的条件构造器
                QueryWrapper<Right> rightQueryWrapper = new QueryWrapper<>();
                rightQueryWrapper.eq("right_code", parentCode);

                //返回最终的schildren
                String schildren = ToolUtil.setSchildren(iRightServiceIml, Integer.parseInt(rightId), rightQueryWrapper);

                if (schildren == null) {//说明父级的代码都写错了，没有这样的代码
                    return new Res(false, null, "#没有这样的权限CODE");
                }
                //设置父级权限的条件构造器
                UpdateWrapper<Right> rightUpdateWrapper = new UpdateWrapper<>();
                rightUpdateWrapper.eq("right_code", parentCode);
                rightUpdateWrapper.set("schildren", schildren);

                boolean update = iRightServiceIml.update(rightUpdateWrapper);


                return new Res(update, null, update ? "保存权限成功" : "保存权限失败");

            } else if (rank.length == 3) {//当数组长度为3，代表父级节点是二级节点 eg:system:role:save
                String parentCode = rank[0]+":"+rank[1];

                //获取父级权限的条件构造器
                QueryWrapper<Right> rightQueryWrapper = new QueryWrapper<>();
                rightQueryWrapper.eq("right_code", parentCode);

                //返回最终的schildren
                String schildren = ToolUtil.setSchildren(iRightServiceIml, Integer.parseInt(rightId), rightQueryWrapper);
                if (schildren == null) {//说明父级的代码都写错了，没有这样的代码
                    return new Res(false, null, "#没有这样的权限CODE");
                }
                //设置父级权限的条件构造器
                UpdateWrapper<Right> rightUpdateWrapper = new UpdateWrapper<>();
                rightUpdateWrapper.eq("right_code", parentCode);
                rightUpdateWrapper.set("schildren", schildren);

                boolean update = iRightServiceIml.update(rightUpdateWrapper);

                return new Res(update, null, update ? "保存权限成功" : "保存权限失败");

            }

        }
        return new Res(true, null, "保存权限成功");
    }

    @ApiOperation(value = "权限管理-删除权限")
    @DeleteMapping("/delete/{id}")
    @Transactional
    public Res deleteRight(@PathVariable String id) {
        Right right = iRightServiceIml.getById(Integer.parseInt(id));

        String schildren = right.getSchildren();//孩子id字符串

        //查是否存在父节点
        String[] split = right.getRightCode().split(":");

        /**
         * 假如有父节点要对父节点的schildren处理
         */

        if (split.length > 1) {

            StringBuilder _parentCode = new StringBuilder(split[0]);
            if (split.length > 2) {
                _parentCode.append(":");
            }
            for (int i = 1; i < split.length-1; i++) {
                _parentCode.append(split[i]);

            }
            String parentCode = _parentCode.toString();
            QueryWrapper<Right> wrapper = new QueryWrapper<>();
            wrapper.eq("right_code", parentCode);
            Right parent = iRightServiceIml.getOne(wrapper);

            //在父节点的schildren中减去即将删除节点的id并保存

            String res = "";//最终的字符串
            String parent_schildren = parent.getSchildren();
            String[] split1 = parent_schildren.split(",");

            if (split1[0].equals(id)) {
                StringBuilder stringBuilder = new StringBuilder();
                for (int i = 1; i < split1.length; i++) {
                    stringBuilder.append(split1[i]);
                    if (i != split1.length - 1) {
                        stringBuilder.append(",");
                    }

                }
                res = stringBuilder.toString();
            } else if (split1[split1.length - 1].equals(id)) {
                StringBuilder stringBuilder = new StringBuilder();
                for (int i = 0; i < split1.length - 1; i++) {
                    stringBuilder.append(split1[i]);
                    if (i != split1.length - 2) {
                        stringBuilder.append(",");
                    }

                }
                res = stringBuilder.toString();
            } else {
                StringBuilder stringBuilder = new StringBuilder();
                for (int i = 0; i < split1.length; i++) {
                    if (split1[i].equals(id)) {
                        continue;
                    }
                    stringBuilder.append(split1[i]);
                    if (i != split1.length - 1) {
                        stringBuilder.append(",");
                    }
                }
                res = stringBuilder.toString();
            }

            //进行设置
            UpdateWrapper<Right> rightUpdateWrapper = new UpdateWrapper<>();
            rightUpdateWrapper.eq("right_code", parentCode);
            rightUpdateWrapper.set("schildren", res);
            iRightServiceIml.update(rightUpdateWrapper);

        }

        /**
         * 没有父节点，直接删除他的所有子节点(就算有，那也要删除)
         */
        if (schildren != null) {//如果有孩子节点

            //删除所有孩子节点
            String[] ids = schildren.split(",");
            for (String s : ids) {
                iRightServiceIml.removeById(Integer.parseInt(s));
            }
            boolean b = iRightServiceIml.removeById(Integer.parseInt(id));
            return new Res(b, null, b ? "删除权限成功" : "删除权限失败");

        }
        boolean b = iRightServiceIml.removeById(Integer.parseInt(id));
        return new Res(b, null, b ? "删除权限成功" : "删除权限失败");
    }



    @ApiOperation(value = "配置权限")
    @PostMapping("/cnf")
    @Transactional

    public Res setRight(@RequestParam String roleId, @RequestParam String rightIds) {
        //找到相应的权限字符串
//        QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();(一对多的方法)
//        roleQueryWrapper.eq("id", Integer.parseInt(roleId));
//        Role role = iRoleServiceIml.getById(Integer.parseInt(roleId));
//        String rights = role.getRoleRights();
//
//        String s = rights + "," + rightIds;
//        String[] split = s.split(",");
//        HashSet<String> characters = new HashSet<>();
//        Collections.addAll(characters, split);
//
//        StringBuilder stringBuilder = new StringBuilder();
//        for (String character : characters) {
//            stringBuilder.append(character);
//            stringBuilder.append(",");
//        }
//        stringBuilder.deleteCharAt(stringBuilder.length() - 1);
//        String res = stringBuilder.toString();
//
//        //增加权限到字符串中
//        UpdateWrapper<Role> wrapper = new UpdateWrapper<>();
//        wrapper.eq("id", Integer.parseInt(roleId));
//        wrapper.set("role_rights", res);
        QueryWrapper<RoleRight> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.eq("role_id", Integer.parseInt(roleId));
        RoleRight roleRight = iRoleRightServiceIml.getOne(roleQueryWrapper);
        String _rights = roleRight.getRightsIds();
        String rights = _rights + rightIds;
        UpdateWrapper<RoleRight> wrapper = new UpdateWrapper<>();
        wrapper.set("rights_ids", rights);
        boolean update = iRoleRightServiceIml.update(wrapper);
        return new Res(update, null, update ? "设置权限成功" : "设置权限失败");

    }

    @ApiOperation(value = "获取角色数据")
    @GetMapping("role/list")
    @Transactional(readOnly = true)
    public Res getRoleRight() {
        List<Role> list = iRoleServiceIml.list();
        return new Res(true, JSON.toJSONString(list),  "设置角色成功");

    }



}
